package com.smartfast4j.common.file;

import com.smartfast4j.common.file.bean.UploadResult;
import com.smartfast4j.qiniu.QiNiuFileService;
import com.smartfast4j.qiniu.bean.QiNiuUploadResult;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by gacl on 2017/10/23.
 */
public class QiNiuFileServiceImpl implements FileService {

    private static Logger logger = Logger.getLogger(QiNiuFileServiceImpl.class);

    /**
     * 文件上传后的存储方式
     */
    private static final String STORAG_TYPE = "SFTP";
    /**
     * 七牛客户端初始化用到的properties配置文件
     */
    private static final String QINIU_CONFIG_FILE_PATH = "config/qiniuConfig.properties";

    private QiNiuFileService qiNiuFileService;

    //使用volatile关键字保其可见性
    volatile private static FileService instance = null;

    /**
     * 获取实例
     * 单例模式是为确保一个类只有一个实例，并为整个系统提供一个全局访问点的一种模式方法。
     从概念中体现出了单例的一些特点：
     （1）、在任何情况下，单例类永远只有一个实例存在
     （2）、单例需要有能力为整个系统提供这一唯一实例
     * @return
     */
    public static FileService getInstance() {
        if(instance != null){//懒汉式
            String className = instance.getClass().getName();
            logger.debug("懒汉式：FileService实例已经存在，直接返回使用，该实例的hashCode="+instance.hashCode()+"，FileService使用的实现类是："+className);
        }else{
            synchronized (FileService.class) {
                if(instance == null){//二次检查
                    instance = new QiNiuFileServiceImpl();
                    String className = instance.getClass().getName();
                    logger.debug("FileService实例还未创建，创建该实例，该实例的hashCode="+instance.hashCode()+"，FileService使用的实现类是："+className);
                }else{
                    String className = instance.getClass().getName();
                    logger.debug("二次检查：FileService实例已经存在，直接返回使用，该实例的hashCode="+instance.hashCode()+"，FileService使用的实现类是："+className);
                }
            }
        }
        return instance;
    }

    private QiNiuFileServiceImpl(){
        qiNiuFileService = new QiNiuFileService(QINIU_CONFIG_FILE_PATH);
    }

    @Override
    public UploadResult uploadFile(String filePath) {
        return uploadFile(filePath,"");
    }

    @Override
    public UploadResult uploadFile(String filePath, String savePath) {
        QiNiuUploadResult qiNiuUploadResult = qiNiuFileService.uploadFile(filePath,savePath);
        return createResult(qiNiuUploadResult);
    }

    @Override
    public UploadResult uploadFile(InputStream inputStream, String fileName) {
        return uploadFile(inputStream,fileName,"");
    }

    @Override
    public List<UploadResult> uploadFile(Map<String, InputStream> inputStreamMap) {
        return uploadFile(inputStreamMap,"");
    }

    @Override
    public UploadResult uploadFile(InputStream inputStream, String fileName, String savePath) {
        QiNiuUploadResult qiNiuUploadResult = qiNiuFileService.uploadFile(inputStream,fileName,savePath);
        return createResult(qiNiuUploadResult);
    }

    @Override
    public List<UploadResult> uploadFile(Map<String, InputStream> inputStreamMap, String savePath) {
        List<UploadResult> uploadResultList = new ArrayList<>();
        for(Map.Entry<String,InputStream> entry:inputStreamMap.entrySet()){
            String fileName = entry.getKey();
            InputStream inputStream = entry.getValue();
            UploadResult uploadResult = uploadFile(inputStream,fileName);
            if(uploadResult==null){
                uploadResult = new UploadResult();
                uploadResult.setOriginalFileName(fileName);
                uploadResult.setIsUploadSuccess(false);
            }
            uploadResultList.add(uploadResult);
        }
        return uploadResultList;
    }

    @Override
    public UploadResult uploadFile(File file, String savePath) {
        QiNiuUploadResult qiNiuUploadResult = qiNiuFileService.uploadFile(file,savePath);
        return createResult(qiNiuUploadResult);
    }

    @Override
    public UploadResult uploadFile(byte[] fileByte, String fileName) {
        return uploadFile(fileByte,fileName);
    }

    @Override
    public UploadResult uploadFile(byte[] fileByte, String fileName, String savePath) {
        QiNiuUploadResult qiNiuUploadResult = qiNiuFileService.uploadFile(fileByte,fileName,savePath);
        return createResult(qiNiuUploadResult);
    }

    @Override
    public UploadResult uploadNetworkFile(String fileUrl) throws MalformedURLException {
        return uploadNetworkFile(fileUrl,"");
    }

    @Override
    public UploadResult uploadNetworkFile(String fileUrl, String fileExt) throws MalformedURLException {
        QiNiuUploadResult qiNiuUploadResult = qiNiuFileService.uploadNetworkFile(fileUrl, fileExt);
        return createResult(qiNiuUploadResult);
    }

    @Override
    public int deleteFile(String directory, String fileName) {
        //TODO 这里的实现有问题
        return qiNiuFileService.deleteFile(directory+fileName);
    }

    @Override
    public Map<String, Integer> batchDeleteFile(String directory, List<String> lstFileName) {
        //TODO 这里的实现有问题
        return qiNiuFileService.batchDeleteFile(lstFileName);
    }

    @Override
    public byte[] downloadFile(String fileUrl) {
        return qiNiuFileService.downloadFile(fileUrl);
    }

    @Override
    public byte[] downloadFile(String directory, String fileName) {
        return new byte[0];
    }

    @Override
    public void downloadFile(String directory, String fileName, String savePath) {

    }

    /**
     * 构建上传返回结果
     * @param qiNiuUploadResult 七牛文件上传结果
     * @return UploadResult
     */
    private UploadResult createResult(QiNiuUploadResult qiNiuUploadResult){
        UploadResult uploadResult = null;
        if(qiNiuUploadResult != null){
            uploadResult = new UploadResult();
            try {
                logger.debug("通过BeanUtils.copyProperties复制sftpUploadResult对象属性值到uploadResult对象");
                BeanUtils.copyProperties(uploadResult, qiNiuUploadResult);
            } catch (Exception e) {
                logger.debug("通过BeanUtils.copyProperties复制sftpUploadResult对象属性值到uploadResult对象异常：" + e.getMessage(), e);
                logger.debug("手动构建uploadResult对象");
                uploadResult.setSavePath(qiNiuUploadResult.getSavePath());
                uploadResult.setDescDetail(qiNiuUploadResult.getDescDetail());
                uploadResult.setExtFieldMap(qiNiuUploadResult.getExtFieldMap());
                uploadResult.setFileSuffix(qiNiuUploadResult.getFileSuffix());
                uploadResult.setFileUrl(qiNiuUploadResult.getFileUrl());
                uploadResult.setIsUploadSuccess(qiNiuUploadResult.isUploadSuccess());
                uploadResult.setNewFileName(qiNiuUploadResult.getNewFileName());
                uploadResult.setOriginalFileName(qiNiuUploadResult.getOriginalFileName());
                uploadResult.setStorageType(qiNiuUploadResult.getStorageType());
                uploadResult.setUseTime(qiNiuUploadResult.getUseTime());
            }
        }
        return uploadResult;
    }
}
